using System;
using System.Collections.Generic;
using System.Text;
using Barrage.GUI.Elements;
using System.Xml;
using Barrage.Global;
using SlimDX;
using Barrage.Meshes.Text;
using Barrage.GUI.Meshes;
using Barrage.Textures;
using System.Globalization;

namespace Barrage.GUI.Templates.Standard
{
    struct StandardGUIButtonListSliderAttributes
    {
        const string XML_SLIDER_LINE_TEXTURE_ATTRIBUTE = "sliderLineTexture";
        const string XML_SLIDER_LINE_HOVER_TEXTURE_ATTRIBUTE = "sliderLineHoverTexture";
        const string XML_SLIDER_MARK_TEXTURE_ATTRIBUTE = "sliderMarkTexture";
        const string XML_TEXTURE_ATTRIBUTE = "texture";
        const string XML_HOVER_TEXTURE_ATTRIBUTE = "hoverTexture";
        const string XML_SLIDER_PADDING_ATTRIBUTE = "sliderPadding";
        const string XML_SLIDER_BORDER_ATTRIBUTE = "sliderBorder";
        const string XML_PADDING_ATTRIBUTE = "padding";
        const string XML_BORDER_ATTRIBUTE = "border";
        const string XML_FONTSIZE_ATTRIBUTE = "fontSize";
        const string XML_TEXTOFFSET_X_ATTRIBUTE = "textOffsetX";
        const string XML_TEXTOFFSET_Y_ATTRIBUTE = "textOffsetY";
        const string XML_SLIDER_MARK_SIZE_X_ATTRIBUTE = "sliderMarkSizeX";
        const string XML_SLIDER_MARK_SIZE_Y_ATTRIBUTE = "sliderMarkSizeY";

        public string SliderLineTexture;
        public string SliderLineHoverTexture;
        public string SliderMarkTexture;
        public string Texture;
        public string HoverTexture;
        public string SliderCoordBorder;
        public string SliderUVBorder;
        public string CoordBorder;
        public string UVBorder;
        public string BitmapFont;
        public float FontSize;
        public Vector2 TextOffset;
        public Vector2 SliderMarkSize;

        const string DEFAULT_SLIDER_LINE_TEXTURE = "Standard/buttonListSliderLine.png";
        const string DEFAULT_SLIDER_LINE_HOVER_TEXTURE = "Standard/buttonListSliderLineHover.png";
        const string DEFAULT_SLIDER_MARK_TEXTURE = "Standard/buttonListSliderMark.png";
        const string DEFAULT_TEXTURE = "Standard/buttonListOption.png";
        const string DEFAULT_HOVER_TEXTURE = "Standard/buttonListOptionHover.png";
        const string DEFAULT_SLIDER_COORDBORDER = "9,9,9,9";
        const string DEFAULT_SLIDER_UVBORDER = "0.03515625,0.28125,0.03515625,0.28125";
        const string DEFAULT_COORDBORDER = "45,45,45,45";
        const string DEFAULT_UVBORDER = "0.0439453125,0.3515625,0.0439453125,0.3515625";
        const string DEFAULT_FONT = "Standard";
        const float DEFAULT_FONTSIZE = 24;
        const float DEFAULT_TEXTOFFSET_X = 0;
        const float DEFAULT_TEXTOFFSET_Y = 10;
        const float DEFAULT_SLIDER_MARK_SIZE_X = 24;
        const float DEFAULT_SLIDER_MARK_SIZE_Y = 24;

        public static StandardGUIButtonListSliderAttributes DefaultValues
        {
            get
            {
                return new StandardGUIButtonListSliderAttributes(
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_HOVER_TEXTURE,
                    DEFAULT_COORDBORDER,
                    DEFAULT_UVBORDER,
                    DEFAULT_FONT,
                    DEFAULT_FONTSIZE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_TEXTURE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_HOVER_TEXTURE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_MARK_TEXTURE,
                    DEFAULT_SLIDER_COORDBORDER,
                    DEFAULT_SLIDER_UVBORDER,
                    new Vector2(DEFAULT_TEXTOFFSET_X,DEFAULT_TEXTOFFSET_Y),
                    new Vector2(DEFAULT_SLIDER_MARK_SIZE_X,DEFAULT_SLIDER_MARK_SIZE_Y)
                     );
            }
        }

        public StandardGUIButtonListSliderAttributes(string texture, string hoverTexture, string coordBorder, string UVBorder, string BitmapFont, float FontSize, string sliderLineTexture, string sliderLineHoverTexture,string sliderMarkTexture,string sliderCoordBorder,string sliderUVBoorder,Vector2 textOffset,Vector2 sliderMarkSize)
        {
            this.Texture = texture;
            this.HoverTexture = hoverTexture;
            this.CoordBorder = coordBorder;
            this.UVBorder = UVBorder;
            this.BitmapFont = BitmapFont;
            this.FontSize = FontSize;
            this.SliderLineTexture = sliderLineTexture;
            this.SliderLineHoverTexture = sliderLineHoverTexture;
            this.SliderMarkTexture = sliderMarkTexture;
            this.SliderCoordBorder = sliderCoordBorder;
            this.SliderUVBorder = sliderUVBoorder;
            this.TextOffset = textOffset;
            this.SliderMarkSize = sliderMarkSize;
        }
        public StandardGUIButtonListSliderAttributes(XmlNode xn)
        {
            Texture = XmlHelper.GetXMLAttribute(xn, XML_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE);
            HoverTexture = XmlHelper.GetXMLAttribute(xn, XML_HOVER_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_HOVER_TEXTURE);
            CoordBorder = XmlHelper.GetXMLAttribute(xn, XML_PADDING_ATTRIBUTE, DEFAULT_COORDBORDER);
            UVBorder = XmlHelper.GetXMLAttribute(xn, XML_BORDER_ATTRIBUTE, DEFAULT_UVBORDER);
            BitmapFont = DEFAULT_FONT;
            FontSize = XmlHelper.ParseXMLFloatAttribute(xn, XML_FONTSIZE_ATTRIBUTE, DEFAULT_FONTSIZE);
            SliderLineTexture = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_LINE_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_TEXTURE);
            SliderLineHoverTexture = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_LINE_HOVER_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_HOVER_TEXTURE);
            SliderMarkTexture = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_MARK_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_MARK_TEXTURE);
            SliderCoordBorder = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_PADDING_ATTRIBUTE, DEFAULT_SLIDER_COORDBORDER);
            SliderUVBorder = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_BORDER_ATTRIBUTE, DEFAULT_SLIDER_UVBORDER);
            TextOffset = XmlHelper.ParseXMLVector2Attribute(xn, XML_TEXTOFFSET_X_ATTRIBUTE, XML_TEXTOFFSET_Y_ATTRIBUTE, new Vector2(DEFAULT_TEXTOFFSET_X, DEFAULT_TEXTOFFSET_Y));
            SliderMarkSize = XmlHelper.ParseXMLVector2Attribute(xn, XML_SLIDER_MARK_SIZE_X_ATTRIBUTE, XML_SLIDER_MARK_SIZE_Y_ATTRIBUTE, new Vector2(DEFAULT_SLIDER_MARK_SIZE_X, DEFAULT_SLIDER_MARK_SIZE_Y));
        }
    }
    /// <summary>
    /// Standard template implementation of the GUIButtonListSlider GUI element
    /// </summary>
    public class StandardGUIButtonListSlider : GUIButtonListSlider
    {
        /// <summary>
        /// \internal Default size of the item for mouse intersection checking. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSize { get { return new Vector2(450, 99); } }

        /// <summary>
        /// \internal Default size of the slider. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSliderSize { get { return new Vector2(380, 18); } }

        /// <summary>
        /// \internal Default offset of the slider. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSliderOffset { get { return new Vector2(0, -20); } }

        const string XML_DEFAULT_ATTRIBUTE = "default";
        private StandardGUIButtonListSliderAttributes attributes;
        TextBoxMesh textMesh;
        BorderedRectangle borderedRectangle;
        BorderedRectangle sliderBorderedRectangle;
        SimpleRectangle sliderMark;
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="layout">Layout that will hold this item</param>
        /// <param name="xn">Xml Node that holds attribute values of this item</param>
        public StandardGUIButtonListSlider(GUILayout layout, XmlNode xn)
            : base(layout, GUITemplateTypes.Standard, xn)
        {
            processDefaultValues(xn);

            float[] coordBorder = parseBorders(attributes.CoordBorder);
            float[] uvBorder = parseBorders(attributes.UVBorder);

            float[] sliderCoordBorder = parseBorders(attributes.SliderCoordBorder);
            float[] sliderUVBorder = parseBorders(attributes.SliderUVBorder);

            borderedRectangle = new BorderedRectangle(TextureManager.Textures[attributes.Texture], Size, coordBorder, uvBorder);
            addMesh(borderedRectangle);

            sliderBorderedRectangle = new BorderedRectangle(TextureManager.Textures[attributes.SliderLineTexture], SliderSize, sliderCoordBorder,sliderUVBorder);
            sliderBorderedRectangle.Offset = SliderOffset;
            addMesh(sliderBorderedRectangle);

            sliderMark = new SimpleRectangle(TextureManager.Textures[attributes.SliderMarkTexture], attributes.SliderMarkSize);
            sliderMark.Offset = DefaultSliderOffset;
            addMesh(sliderMark);

            BitmapFont f = BitmapFontManager.Fonts[attributes.BitmapFont];
            float scale = attributes.FontSize / f.FontInfo.LineHeight;
            textMesh = new TextBoxMesh(f, new TextBoxDrawProperties(TextAlignment.Center, Size, scale, VerticalAlignment.Center, attributes.TextOffset));
            textMesh.Text = Text;
            addMesh(textMesh);
        }

        void processDefaultValues(XmlNode xn)
        {
            bool doNotLoadDefaults = XmlHelper.GetXMLAttribute(xn, XML_DEFAULT_ATTRIBUTE).Equals("false");
            if (doNotLoadDefaults)
                attributes = new StandardGUIButtonListSliderAttributes(xn);
            else
                attributes = StandardGUIButtonListSliderAttributes.DefaultValues;

        }

        /// <summary>
        /// \internal Gets / Sets slider text
        /// </summary>
        public override string Text { set { textMesh.Text = value; base.Text = value; } }

        private float[] parseBorders(string source)
        {
            float[] border = new float[4] { 0, 0, 0, 0 };
            if (source.Length == 0) return border;
            string[] borderStrings = source.Split(',');
            for (int i = 0; i < Math.Min(4, borderStrings.Length); i++)
            {
                Single.TryParse(borderStrings[i], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out border[i]);
            }
            return border;
        }

        /// <summary>
        /// \internal Updates matrices and item logic
        /// </summary>
        protected override void DoUpdate()
        {
            sliderMark.Offset=new Vector2(-DefaultSliderSize.X/2f+DefaultSliderSize.X*Percent,0) + DefaultSliderOffset;
            base.DoUpdate();
            UpdateHover();
            
        }

        void UpdateHover()
        {
            borderedRectangle.Materials[0].Texture = TextureManager.Textures[Selected ? attributes.HoverTexture : attributes.Texture];
            sliderBorderedRectangle.Materials[0].Texture = TextureManager.Textures[Selected ? attributes.SliderLineHoverTexture : attributes.SliderLineTexture];
        }

        /// <summary>
        /// \internal Clear resources
        /// </summary>
        public override void Dispose()
        {
            textMesh = null;
            borderedRectangle = null;
            sliderBorderedRectangle = null;
            sliderMark = null;
            base.Dispose();
        }

    }
}
